/*
Zachs really really bad Ai!!!1!
*/
#pragma once

#include "math.h"
#include "time.h"
#include "reader.h"
#include <string>

// Added 11/26/07
#include <list>
#include "Tiles.h"
#include "Branch.h"
#include "GfxStats.h"
#include "reader.h"

// Added 01/14/08
#include "d3dUtil.h"
#include "Enum.h"

//static bool human;


class Player
{
protected:

	// added to class 2/18/08 -Cai
	char fileName[24];

	//This sets up the Tile Map List
	std::list<Tiles> trunkTiles;
	std::list<Tiles>::iterator trunkIterator;
	std::list<Branch> branchTiles;
	std::list<Branch>::iterator branchIterator;
	std::list<Branch>::iterator branchIter;
	GfxStats* mGfxStats;
	std::list<Tiles>::iterator cursorIter;



	std::list<Tiles> trunkTiles2;
	std::list<Tiles>::iterator trunkIterator2;
	std::list<Branch> branchTiles2;
	std::list<Branch>::iterator branchIterator2;
	std::list<Branch>::iterator branchIter2;
	std::list<Tiles>::iterator cursorIter2;




					//[Node][Rank]
	Spell SpellHolder[4][3];	// Holds the spell coordentantes for 4 nodes
	Trunk trunk;				// Holds the info for the Trunk;
	int Health;					// Holds the life of the player/Ai or .... ya its 100 so shut up.. noob...
	//int BranchNum;			// Keep track of the Branch they are on, this should only be 0 - 3 ( or 1 - 4)
	int BranchLoc;				// Keeps track of where they are on the branch, IE 0 - 29 ( or 1 -  30)

	// Keep track of where they are on the trunk even if they are on a tree. This will hold where they retur to.
	// This should only be from 0 - 19 ( or 1 -20)
	int TrunkLoc;
	bool Dead;					// are you dead man?


	PLAYERID pID;

	// added 01/14/08 ( Monday baby!)
	/* Copied from Wazewars.cpp to make sure i had all the movement variables, not all will be used*/
	bool onBranch;
	bool atFront;
	int frontCtr;

	IDirect3DTexture9* mLifeBar;
	D3DXVECTOR3 mLifeBarCenter;
	D3DXVECTOR3 mLifeBarPos;

	IDirect3DTexture9* mPlayerPortrait;
	D3DXVECTOR3 mPlayerPotraitCenter;
	D3DXVECTOR3 mPlayerPortraitPos;

	bool spellTile;
	//static int rank;
	//static int nodeID;
	bool spellTriggered;
	bool castSpell;

	bool movingForward;
	int spellID;
	// added 01/16/08


	float halfTileWidth;

	//bool onBranch;
	//bool atFront;
	//int frontCtr = 0;



	float dxt;
	float dyt;
	float dxt2;
	float dyt2;

//	bool spellTile;
	int rank;
	int nodeID;
	bool humanOpponent;
	
//	bool spellTriggered;
//	bool movingForward;

	/*remove once working
			static bool onBranch = false;
	static bool atFront = false;
	static int frontCtr = 0;

	static float dxt;
	static float dyt;
	static float dxt2;
	static float dyt2;

	static float dxtp2;
	static float dytp2;
	static float dxt2p2;
	static float dyt2p2;


	bool spellTile;
	static int rank;
	static int nodeID;
	static bool spellTriggered = false;
	static bool movingForward = false;*/

	bool endofBranch(int id);

public:

	 float dx;
 float dy;

	Player(std::string filename, float x, float y, PLAYERID playerID, bool h);
	~Player();

	virtual bool updateMovement(Player *player){return true;}

	void setSingleHuman() {humanOpponent = false;}
	void setMultHuman() {humanOpponent = true;}
	bool getHuman() {return humanOpponent;}
	/*
	//HR(D3DXCreateTextureFromFile(gd3dDevice, "LifeBar.png", &mLifeBar));
	//HR(D3DXCreateTextureFromFile(gd3dDevice, "GSP2.png", &mAvaGuy));
	//HR(D3DXCreateTextureFromFile(gd3dDevice, "GSP1.png", &mAvaGirl));

	mLifeBarCenter = D3DXVECTOR3(256.0f, halfTileWidth, 0.0f);
	mLifeBarPos = D3DXVECTOR3(0.0f, -300.0f, 0.0f);

	mAvaGuyCenter = D3DXVECTOR3(halfTileWidth, tileWidth, 0.0f);
	mAvaGuyPos = D3DXVECTOR3(-620.0f, 0.0f, 0.0f);

	mAvaGirlCenter = D3DXVECTOR3(halfTileWidth, tileWidth, 0.0f);
	mAvaGirlPos = D3DXVECTOR3(620.0f, 0.0f, 0.0f);

	*/

	PLAYERID getPlayerID() { return pID; };

	//set and load texture files
	void setPortraitTex();
	IDirect3DTexture9* getPortraitTex() { return mPlayerPortrait; };

	//set and get position and center
	void setPlayerPortraitCenter();
	D3DXVECTOR3 getPlayerPortraitCenter() { return mPlayerPotraitCenter; };

	void setPlayerPortraitPos();
	float getPlayerPortraitPosX() { return mPlayerPortraitPos.x; };
	float getPlayerPortraitPosY() { return mPlayerPortraitPos.y; };
	
	//set and load life bar textures
	void setLifeBarTex();
	IDirect3DTexture9* getLifeBarTex() { return mLifeBar; };

	void setLifeBarCenter();
	D3DXVECTOR3 getLifeBarCenter() { return mLifeBarCenter; };

	void setLifeBarPos();
	D3DXVECTOR3 getLifeBarPos() { return mLifeBarPos; };

	float getdx() { return dx; }
	float getdy() { return dy; }
	//float getdxp2() { return dxp2; }
	//float getdyp2() { return dyp2; }
	void addgetdx(float num) { dx = dx + num; }
	void addgetdy(float num) { dy = dy + num; }
	//void addgetdxp2(float num) { dxp2 = dxp2 + num; }
	//void addgetdyp2(float num) { dyp2 = dyp2 + num; }
	void setdx(float num) { dx = num; }
	void setdy(float num) { dy = num; }	
	//void setdxp2(float num) { dxp2 = num; }
	//void setdyp2(float num) { dyp2 = num; }	


	int getHealth() { return Health; }
	void addHealth( int Damage) { Health = Health - Damage; if(Health <= 0) { Dead = true; } }
	void update();
	void setTrunkLoc( int Trunknum ) { TrunkLoc = Trunknum; }
	//void setBranchNum( int numBranch) { BranchNum = numBranch; }
	void setBranchLoc( int locBranch) { BranchLoc = locBranch; }
	//int getBranchNum() { return BranchNum; }
	int getBranchLoc() { return BranchLoc; }
	int getTrunkLoc() { return TrunkLoc; }
	void setSpell(Spell spell,int NodeNum, int RankNum ) { SpellHolder[NodeNum][RankNum] = spell; } 
	void setTrunk(Trunk trunks) { trunk = trunks; }

	bool getTrunkIteratorEnd() { if(trunkIterator == trunkTiles.end()) { return false; } else { return true; } }
	void setTrunkIteratorBegin(){ trunkIterator = trunkTiles.begin(); }
	void incrementTrunkIterator() { trunkIterator++; }
	void decrementTrunkIterator() { trunkIterator--; }
	float getTrunkTileFrontX() { trunkTiles.front().getX();}
	float getTrunkTileFrontY() { trunkTiles.front().getY();}
	float getTrunkIteratorX() { return trunkIterator->getX(); } 
	float getTrunkIteratorY() { return trunkIterator->getY(); } 
	float getBranchIteratorX() { return branchIterator->getX(); } 
	float getBranchIteratorY() { return branchIterator->getY(); } 

	RECT getTrunkIteratorRECT() { return trunkIterator->getRect(); }
	D3DXVECTOR3 getTrunkIteratorCenter() { return trunkIterator->getCenter(); }
	D3DXVECTOR3 getBranchIteratorCenter() { return branchIterator->getCenter(); }
	void incrementBranchIterator() { branchIterator++; }
	void decrementBranchIterator() { branchIterator--; }
	void setBranchIteratorBegin(){ branchIterator = branchTiles.begin(); }
	bool getBranchIteratorIsCoolDown() { return branchIterator->isCoolDown(); }

	void increaseTrunkIterator() { trunkIterator++; }
	bool getTrunkIteratorEndIf() { if(trunkIterator == trunkTiles.end()) { return false; } else { return true; } } 
	bool getTrunkIteratorIsNodeTile() { return trunkIterator->isNodeTile(); }
	void setTrunkIteratorFree() { trunkIterator->FreeNode(); }
	void setTrunkTilesPopBack() { trunkTiles.pop_back(); }

	bool getBranchIteratorEndIf() { if(branchIterator == branchTiles.end()) { return false; } else { return true; } } 
	RECT getBranchIteratorRECT() { return branchIterator->getRect(); }

	void readerSetUp();
	void createSpellTree(fileReader *reader, int nodeNbr, SpellType spell);


	bool moveCursor(Button button, Player *player);
	int getFirstBranchButton(int nodeID);
	void setCoolDown(int nodeID, int rank, bool coolDownState);
	void updateCoolDowns(float dt);

	void setCastSpell(bool cast) { castSpell = cast; }
	bool getCastSpell(void) { return castSpell; }

		bool spellAlive;
	void setSpellAlive(bool alive) { spellAlive = alive; }
	bool getSpellAlive(void) { return spellAlive; }

};



class AI : public Player
{
private:
	int TargetSpell; // holds the Spell to be cast


	// holds the point when the AI need to re-calculate what he is aiming for ( It needs to find a new spell to cast this one is castededed)
	int TargetEnd; 
	
	//int Movement; Zach was thinking he might need to store the movement he wants to press, but then thought nah i dont want too....
	int NextButten; // This wil hold the next butted that needs to be pressed;
	int Butten;

	bool pressed;
	bool Target; // hold T or F if the AI has reched the spell to be cast
	bool Branch; // on branch or not

public:
	//AI(void);
	AI(std::string filename, float x, float y, PLAYERID playerID, bool h);
	~AI();
	void setTarget(int spellTarget, int endTarget) { TargetSpell = spellTarget; TargetEnd = endTarget; }
	void update();
	void getNewTarget();					// This will retarget the spell to get casted..
	bool updateMovement(Player *player);					// This will roll a random number tosee if it moves in the direction it wants too....; 
	
	void setButten(int butten) { NextButten = butten; }

	int getNextButten() { return NextButten; }
	
	void setBranchTrue() { Branch = true; }
	void setBranchFalse() { Branch = false; }
	bool getOnBranch() { return Branch; }
	int getTargetSpell() { return TargetSpell; }
	int getTargetEnd() { return TargetEnd; }
	void changeTargetSpell() { TargetSpell = 0; }

};





// THIS IS A BACK UP OF THE READER CLASS LIST ANISHALIZERSER


/*	int nodeNbr = 0;

	//temp for now, need to add this functionality to the reader class or editor, shdn't be set how it is now
	SpellType temp = TrunkTile;

	char fileName[24] = "Test.txt";

	File file;
	
	fileReader *reader = new fileReader();
	
	file = reader->readFile(fileName);
	
	reader->setSpell(file);

	// Pushes the Trunk onto the list to be drawn
	for(int i = 0; i < 20; i++)
	{
		//we are at a node tile
		if(i%5 == 4)
		{
			//setting spell type
			switch(i)
			{
				case 4:
					temp = Fire;
					break;
				case 9:
					temp = Water;
					break;
					
				case 14:
					temp = Wind;
					break;
				case 19:
					temp = Earth;
					break;
				default:
					temp = TrunkTile;
					break;
			}

			Tiles tile((float)reader->TrunkP.mPointX[i], (float) reader->TrunkP.mPointY[i], 0.0f, NodeTile, temp, false, nodeNbr);
			trunkTiles.push_back(tile);
			player.pushTrunkTile(tile);
		
			//create spell tree for node
			createSpellTree(reader, nodeNbr, temp, 1);
			
			nodeNbr++;

		}
		else
		{

			//spell type = trunk, tileType = Trunk_Branch
			Tiles tile((float)reader->TrunkP.mPointX[i], (float) reader->TrunkP.mPointY[i], 0.0f, Trunk_Branch, TrunkTile);
			trunkTiles.push_back(tile);
			player.pushTrunkTile(tile);


		}

	}

	nodeNbr = 0;
	// Pushes the Trunk onto the list to be drawn
	for(int i = 0; i < 20; i++)
	{
		//we are at a node tile
		if(i%5 == 4)
		{
			//setting spell type
			switch(i)
			{
				case 4:
					temp = Fire;
					break;
				case 9:
					temp = Water;
					break;
					
				case 14:
					temp = Wind;
					break;
				case 19:
					temp = Earth;
					break;
				default:
					temp = TrunkTile;
					break;
			}

			Tiles tile1((float)reader->TrunkP.mPointX[i], (float) reader->TrunkP.mPointY[i], 0.0f, NodeTile, temp, false, nodeNbr);
			trunkTiles2.push_back(tile1);
		
			//create spell tree for node
			createSpellTree(reader, nodeNbr, temp, 2);
			
			nodeNbr++;

		}
		else
		{
			//spell type = trunk, tileType = Trunk_Branch
			Tiles tile1((float)reader->TrunkP.mPointX[i], (float) reader->TrunkP.mPointY[i], 0.0f, Trunk_Branch, TrunkTile);
			trunkTiles2.push_back(tile1);
		}

	}

	//set cursor starting position
	gameCursorPosition = D3DXVECTOR3(trunkTiles.front().getX(), trunkTiles.front().getY(), 0.0f);
	//gameCursorPosition = D3DXVECTOR3(player.getTrunkTileFrontX(), player.getTrunkTileFrontY(), 0.0f);

	gameCursorPosition2 = D3DXVECTOR3(trunkTiles2.front().getX(), trunkTiles2.front().getY(), 0.0f);

	//set iterator
	trunkIterator = trunkTiles.begin();
	player.setTrunkIteratorBegin();

	trunkIterator++;
	player.incrementTrunkIterator();

	cursorIter = trunkTiles.begin();
	player.setCursorIteratorBegin();
	//free reader

	//set iterator
	trunkIterator2 = trunkTiles2.begin();
	trunkIterator2++;

	cursorIter2 = trunkTiles2.begin();
	//free reader
	delete reader;

}

void MazeWars::createSpellTree(fileReader *reader, int nodeNbr, SpellType spell, int playerNum)
{

	//aligning rank one spells up with proper node on trunk
	float dx1[4];
	float dy1[4];

	//align rank 2 with rank 1
	float dx;
	float dy;
	
	//align rank 3 with rank 2
	float dx2;
	float dy2;  
	bool front = false;

		//assigning translation values
	dx1[0] = (reader->TrunkP.mPointX[4]);
	dy1[0] = reader->TrunkP.mPointY[4];

	dx1[1] = (reader->TrunkP.mPointX[9]);
	dy1[1] = reader->TrunkP.mPointY[9];

	dx1[2] = (reader->TrunkP.mPointX[14]);
	dy1[2] = reader->TrunkP.mPointY[14];

	dx1[3] = (reader->TrunkP.mPointX[19]);
	dy1[3] = reader->TrunkP.mPointY[19];



	dx = (reader->SpellHolder[nodeNbr][0].mPointX[9] + dx1[nodeNbr]);
	dy = (reader->SpellHolder[nodeNbr][0].mPointY[9] + dy1[nodeNbr]);
	
	dx2 = (reader->SpellHolder[nodeNbr][1].mPointX[9] + dx);
	dy2 = (reader->SpellHolder[nodeNbr][1].mPointY[9] + dy);

	if(playerNum == 1)
	{

		//Pushes Rank 1 onto the list to be drawn
		for(int i = 0; i < 10; i++)
		{	
			if(i == 0)
				front = true;
			else
				front = false;

			if(i == 9)
			{
				Branch branchTile((float)reader->SpellHolder[nodeNbr][0].mPointX[i] + dx1[nodeNbr], (float) reader->SpellHolder[nodeNbr][0].mPointY[i] + dy1[nodeNbr], 0.0f, SPELLTILE, spell, false, nodeNbr, front, 1, true);
				branchTiles.push_back(branchTile);
				//player.pushBranchTile(branchTile);

			}
			else
			{
				Branch branchTile((float)reader->SpellHolder[nodeNbr][0].mPointX[i] + dx1[nodeNbr], (float) reader->SpellHolder[nodeNbr][0].mPointY[i] + dy1[nodeNbr], 0.0f, Trunk_Branch, spell, false, nodeNbr, front, 1);
				branchTiles.push_back(branchTile);
				//player.pushBranchTile(branchTile);
			}

		}
		
		// Pushes Rank 2 onto the list to be drawn
		for(int i = 0; i < 10; i++)
		{	
			front = false;

		

			//added 10/21/07 @ 6:07
			if(i == 9)
			{
				Branch branchTile((float)reader->SpellHolder[nodeNbr][1].mPointX[i] + dx, (float) reader->SpellHolder[nodeNbr][1].mPointY[i] + dy, 0.0f, SPELLTILE, spell, false, nodeNbr, front, 2, true);
				branchTiles.push_back(branchTile);
				//player.pushBranchTile(branchTile);

			}
			else
			{
				Branch branchTile((float)reader->SpellHolder[nodeNbr][1].mPointX[i] + dx, (float) reader->SpellHolder[nodeNbr][1].mPointY[i] + dy, 0.0f, Trunk_Branch, spell, false, nodeNbr, front, 2);
				branchTiles.push_back(branchTile);
				//player.pushBranchTile(branchTile);

			}
		}

		// Pushed Rank 3 onto the list to be drawn
		for(int i = 0; i < 10; i++)
		{		
			//mistake: this is the 3rd rank of the nodes spell tree, front shd be false, only needs to be true for first
			//rank, first tile

			front = false;
			

			//added 10/21/07 @ 6:07
			if(i == 9)
			{
				Branch branchTile((float)reader->SpellHolder[nodeNbr][2].mPointX[i] + dx2, (float) reader->SpellHolder[nodeNbr][2].mPointY[i] + dy2, 0.0f, SPELLTILE, spell, false, nodeNbr, front, 3, true);
				branchTiles.push_back(branchTile);
				//player.pushBranchTile(branchTile);

			}
			else
			{
				Branch branchTile((float)reader->SpellHolder[nodeNbr][2].mPointX[i] + dx2, (float) reader->SpellHolder[nodeNbr][2].mPointY[i] + dy2, 0.0f, Trunk_Branch, spell, false, nodeNbr, front, 3);
				branchTiles.push_back(branchTile);
				//player.pushBranchTile(branchTile);

			}
		}
	}
	else
	{

		//Pushes Rank 1 onto the list to be drawn
		for(int i = 0; i < 10; i++)
		{	
			if(i == 0)
				front = true;
			else
				front = false;

			if(i == 9)
			{

				Branch branchTile1((float)reader->SpellHolder[nodeNbr][0].mPointX[i] + dx1[nodeNbr], (float) reader->SpellHolder[nodeNbr][0].mPointY[i] + dy1[nodeNbr], 0.0f, SPELLTILE, spell, false, nodeNbr, front, 1, true);
				branchTiles2.push_back(branchTile1);
			}
			else
			{

				Branch branchTile1((float)reader->SpellHolder[nodeNbr][0].mPointX[i] + dx1[nodeNbr], (float) reader->SpellHolder[nodeNbr][0].mPointY[i] + dy1[nodeNbr], 0.0f, Trunk_Branch, spell, false, nodeNbr, front, 1);
				branchTiles2.push_back(branchTile1);
			}

		}
		
		// Pushes Rank 2 onto the list to be drawn
		for(int i = 0; i < 10; i++)
		{	
			front = false;

		

			//added 10/21/07 @ 6:07
			if(i == 9)
			{
				Branch branchTile1((float)reader->SpellHolder[nodeNbr][1].mPointX[i] + dx, (float) reader->SpellHolder[nodeNbr][1].mPointY[i] + dy, 0.0f, SPELLTILE, spell, false, nodeNbr, front, 2, true);
				branchTiles2.push_back(branchTile1);
			}
			else
			{
				Branch branchTile1((float)reader->SpellHolder[nodeNbr][1].mPointX[i] + dx, (float) reader->SpellHolder[nodeNbr][1].mPointY[i] + dy, 0.0f, Trunk_Branch, spell, false, nodeNbr, front, 2);
				branchTiles2.push_back(branchTile1);
			}
		}

		// Pushed Rank 3 onto the list to be drawn
		for(int i = 0; i < 10; i++)
		{		
			//mistake: this is the 3rd rank of the nodes spell tree, front shd be false, only needs to be true for first
			//rank, first tile

			front = false;
			

			//added 10/21/07 @ 6:07
			if(i == 9)
			{

				Branch branchTile1((float)reader->SpellHolder[nodeNbr][2].mPointX[i] + dx2, (float) reader->SpellHolder[nodeNbr][2].mPointY[i] + dy2, 0.0f, SPELLTILE, spell, false, nodeNbr, front, 3, true);
				branchTiles2.push_back(branchTile1);
			}
			else
			{

				Branch branchTile1((float)reader->SpellHolder[nodeNbr][2].mPointX[i] + dx2, (float) reader->SpellHolder[nodeNbr][2].mPointY[i] + dy2, 0.0f, Trunk_Branch, spell, false, nodeNbr, front, 3);
				branchTiles2.push_back(branchTile1);
			}
		}




	}
}
*/

